package com.skywork.service.base;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.skywork.domain.base.MyMapper;

@Transactional(readOnly = true, rollbackFor = { Exception.class })
public abstract class BaseService<T> {

	protected final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private ApplicationContext context;

	private MyMapper<T> myMapper;

	@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
	public T selectByPrimaryKey(long id) {
		setMyMapper();
		return myMapper.selectByPrimaryKey(id);
	}

	@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
	public List<T> select(T obj) {
		setMyMapper();
		return myMapper.select(obj);
	}

	@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
	public T selectOne(T obj) {
		setMyMapper();
		return myMapper.selectOne(obj);
	}

	@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
	public int count(T obj) {
		setMyMapper();
		return myMapper.selectCount(obj);
	}

	public void insertUseGeneratedKeys(T obj) {
		setMyMapper();
		myMapper.insertUseGeneratedKeys(obj);
	}

	public void updateByPrimaryKey(T obj) {
		setMyMapper();
		myMapper.updateByPrimaryKey(obj);
	}

	@SuppressWarnings("unchecked")
	private void setMyMapper() {
		if (myMapper == null) {
			Type genType = getClass().getGenericSuperclass();
			if (genType instanceof ParameterizedType) {
				Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
				String className = params[0].getTypeName();
				String mapperName = className.substring(className.lastIndexOf(".") + 1);
				this.myMapper = (MyMapper<T>) context.getBean(mapperName.substring(0, 1).toLowerCase() + mapperName.substring(1) + "Mapper");
			}
		}
	}

	// @Autowired
	// private SqlSessionFactoryBean sqlSessionFactoryBean;
	//
	// public void finaAll() {
	// sqlSessionFactory.openSession();
	// }

}
